package clue

import (
	"context"
	"errors"
	clueDto "git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/dto/clue"
	"git.mycaigou.com/gfyx/micro-gfyx-api/infrastructure/repository/clue"
	cluePb "git.mycaigou.com/gfyx/micro-gfyx-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/clue"
	"git.myscrm.cn/golang/stark/v4"
)

type CustomerManageService struct {
	customerManageRepository clue.CustomerManageRepositoryIface
}

func NewCustomerManageService(customerManageRepository clue.CustomerManageRepositoryIface) CustomerManageServiceIface {
	return &CustomerManageService{customerManageRepository: customerManageRepository}
}

func (s *CustomerManageService) MyResponsibleCustomers(ctx context.Context, request *clueDto.MyResponsibleCustomersRequest) (*clueDto.MyResponsibleCustomersResponse, error) {
	params := &cluePb.CustomerListRequest{
		Page:            request.Page,
		PageSize:        request.PageSize,
		Keyword:         request.Keyword,
		Group:           request.Group,
		AreaCodes:       request.AreaCodes,
		CompanyLevel:    request.CompanyLevel,
		CompanyIdentity: request.CompanyIdentity,
		CompanyLabel:    request.CompanyLabel,
		CompanyType:     request.CompanyType,
	}
	customers, err := s.customerManageRepository.MyResponsibleCustomers(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "my responsible customers request: %v, error: %v", params, err)
		return nil, err
	}
	response := &clueDto.MyResponsibleCustomersResponse{
		List:  make([]*clueDto.CustomerListItem, 0),
		Total: customers.Total,
	}
	for _, customer := range customers.List {
		companyLevel := make([]*clueDto.CustomerLabelItem, 0)
		companyLabel := make([]*clueDto.CustomerLabelItem, 0)
		for _, label := range customer.CompanyLevel {
			companyLevel = append(companyLevel, &clueDto.CustomerLabelItem{
				Label:  label.Label,
				Remark: label.Remark,
			})
		}
		for _, label := range customer.CompanyLabel {
			companyLabel = append(companyLabel, &clueDto.CustomerLabelItem{
				Label:  label.Label,
				Remark: label.Remark,
			})
		}
		response.List = append(response.List, &clueDto.CustomerListItem{
			Id:                       customer.Id,
			CompanyName:              customer.CompanyName,
			OrganizingCode:           customer.OrganizingCode,
			CompanyLogo:              customer.CompanyLogo,
			Group:                    customer.Group,
			BusinessStatus:           customer.BusinessStatus,
			TopCompanyName:           customer.TopCompanyName,
			TopCompanyOrganizingCode: customer.TopCompanyOrganizingCode,
			CompanyIdentity:          customer.CompanyIdentity,
			CompanyType:              customer.CompanyType,
			CompanyLevel:             companyLevel,
			CompanyLabel:             companyLabel,
			Province:                 customer.Province,
			City:                     customer.City,
			ProvinceCode:             customer.ProvinceCode,
			CityCode:                 customer.CityCode,
			ClueCnt:                  customer.ClueCnt,
			ReportCnt:                customer.ReportCnt,
			BidCnt2Year:              customer.BidCnt_2Year,
			TakeLandCnt2Year:         customer.TakeLandCnt_2Year,
			CommencePermitCnt2Year:   customer.CommencePermitCnt_2Year,
			SellProjectCnt2Year:      customer.SellProjectCnt_2Year,
			CooperationCaseCnt2Year:  customer.CooperationCaseCnt_2Year,
			CreditLevel:              customer.CreditLevel,
			ResponsibleUserName:      customer.ResponsibleUserName,
			ResponsibleUserId:        customer.ResponsibleUserId,
			CreatedBy:                customer.CreatedBy,
			CreatedByUserName:        customer.CreatedByUserName,
			CreatedOn:                customer.CreatedOn,
		})
	}
	return response, nil
}

func (s *CustomerManageService) CustomerList(ctx context.Context, request *clueDto.CustomerRequest) (*clueDto.CustomerResponse, error) {
	params := &cluePb.CustomerListRequest{
		Page:               request.Page,
		PageSize:           request.PageSize,
		Keyword:            request.Keyword,
		Group:              request.Group,
		AreaCodes:          request.AreaCodes,
		CompanyLevel:       request.CompanyLevel,
		CompanyIdentity:    request.CompanyIdentity,
		CompanyLabel:       request.CompanyLabel,
		ResponsibleUserIds: request.ResponsibleUserIds,
		Category:           "all", // 区分是全国还是个人
		CompanyType:        request.CompanyType,
	}
	customers, err := s.customerManageRepository.CustomerList(ctx, params)
	if err != nil {
		stark.Logger.Errorf(ctx, "CustomerList request: %v, error: %v", params, err)
		return nil, err
	}
	response := &clueDto.CustomerResponse{
		List:  make([]*clueDto.CustomerListItem, 0),
		Total: customers.Total,
	}
	for _, customer := range customers.List {
		companyLevel := make([]*clueDto.CustomerLabelItem, 0)
		companyLabel := make([]*clueDto.CustomerLabelItem, 0)
		for _, label := range customer.CompanyLevel {
			companyLevel = append(companyLevel, &clueDto.CustomerLabelItem{
				Label:  label.Label,
				Remark: label.Remark,
			})
		}
		for _, label := range customer.CompanyLabel {
			companyLabel = append(companyLabel, &clueDto.CustomerLabelItem{
				Label:  label.Label,
				Remark: label.Remark,
			})
		}
		response.List = append(response.List, &clueDto.CustomerListItem{
			Id:                       customer.Id,
			CompanyName:              customer.CompanyName,
			OrganizingCode:           customer.OrganizingCode,
			CompanyLogo:              customer.CompanyLogo,
			BusinessStatus:           customer.BusinessStatus,
			Group:                    customer.Group,
			TopCompanyName:           customer.TopCompanyName,
			TopCompanyOrganizingCode: customer.TopCompanyOrganizingCode,
			CompanyIdentity:          customer.CompanyIdentity,
			CompanyType:              customer.CompanyType,
			CompanyLevel:             companyLevel,
			CompanyLabel:             companyLabel,
			Province:                 customer.Province,
			City:                     customer.City,
			ProvinceCode:             customer.ProvinceCode,
			CityCode:                 customer.CityCode,
			ClueCnt:                  customer.ClueCnt,
			ReportCnt:                customer.ReportCnt,
			BidCnt2Year:              customer.BidCnt_2Year,
			TakeLandCnt2Year:         customer.TakeLandCnt_2Year,
			CommencePermitCnt2Year:   customer.CommencePermitCnt_2Year,
			SellProjectCnt2Year:      customer.SellProjectCnt_2Year,
			CooperationCaseCnt2Year:  customer.CooperationCaseCnt_2Year,
			CreditLevel:              customer.CreditLevel,
			ResponsibleUserName:      customer.ResponsibleUserName,
			ResponsibleUserId:        customer.ResponsibleUserId,
			CreatedBy:                customer.CreatedBy,
			CreatedByUserName:        customer.CreatedByUserName,
			CreatedOn:                customer.CreatedOn,
		})
	}
	return response, nil
}

func (s *CustomerManageService) CustomerGroupOption(ctx context.Context, request *clueDto.GroupOptionRequest) (*clueDto.GroupOptionResponse, error) {
	params := &cluePb.CustomerGroupOptionRequest{}
	option, err := s.customerManageRepository.CustomerGroupOption(ctx, params)
	if err != nil {
		return nil, err
	}
	return &clueDto.GroupOptionResponse{List: option.List}, nil
}

func (s *CustomerManageService) SaveCustomer(ctx context.Context, request *clueDto.SaveCustomerRequest) (*clueDto.SaveCustomerResponse, error) {
	params := &cluePb.SaveCustomerRequest{
		Id:                request.Id,
		CompanyName:       request.CompanyName,
		OrganizingCode:    request.OrganizingCode,
		ResponsibleUserId: request.ResponsibleUserId,
		Group:             request.Group,
	}
	response, err := s.customerManageRepository.SaveCustomer(ctx, params)
	if err != nil {
		return nil, err
	}
	return &clueDto.SaveCustomerResponse{
		Id: response.Id,
	}, nil
}

func (s *CustomerManageService) DeleteCustomer(ctx context.Context, request *clueDto.DeleteCustomerRequest) (*clueDto.DeleteCustomerResponse, error) {
	params := &cluePb.DeleteCustomerRequest{
		Id: request.Id,
	}
	_, err := s.customerManageRepository.DeleteCustomer(ctx, params)
	if err != nil {
		return nil, err
	}

	return &clueDto.DeleteCustomerResponse{}, nil
}

func (s *CustomerManageService) ImportFile(ctx context.Context, request *clueDto.ImportFileRequest) (*clueDto.ImportFileResponse, error) {
	params := &cluePb.ImportCustomerRequest{
		FileId: request.FileId,
	}
	response, err := s.customerManageRepository.ImportCustomer(ctx, params)
	if err != nil {
		return nil, err
	}
	return &clueDto.ImportFileResponse{
		JobId: response.JobId,
		Total: response.Total,
	}, nil
}

func (s *CustomerManageService) ImportStatus(ctx context.Context, request *clueDto.ImportStatusRequest) (*clueDto.ImportStatusResponse, error) {
	params := &cluePb.ImportCustomerStatusRequest{}
	response, err := s.customerManageRepository.ImportCustomerStatus(ctx, params)
	if err != nil {
		return nil, err
	}
	return &clueDto.ImportStatusResponse{
		Status:       response.Status,
		ImportTime:   response.ImportTime,
		SucceedCount: response.SucceedCount,
		FailedCount:  response.FailedCount,
		FileId:       response.FileId,
	}, nil
}

func (s *CustomerManageService) ImportList(ctx context.Context, request *clueDto.ImportListRequest) (*clueDto.ImportListResponse, error) {
	params := &cluePb.ImportCustomerListRequest{
		Keyword:   request.CompanyName,
		StartTime: request.StartTime,
		EndTime:   request.EndTime,
		Status:    request.Status,
		Page:      request.Page,
		PageSize:  request.PageSize,
	}
	customerList, err := s.customerManageRepository.ImportCustomerList(ctx, params)
	if err != nil {
		return nil, err
	}
	response := &clueDto.ImportListResponse{
		Total: customerList.Total,
		List:  make([]*clueDto.ImportFileItem, 0),
	}

	for _, customer := range customerList.List {
		response.List = append(response.List, &clueDto.ImportFileItem{
			Id:                  customer.Id,
			FileId:              customer.FileId,
			Status:              customer.Status,
			CompanyName:         customer.CompanyName,
			ResponsibleUserName: customer.ResponsibleUserName,
			ResponsiveUserId:    customer.ResponsibleUserId,
			CustomerGroup:       customer.CustomerGroup,
			Remark:              customer.Remark,
			CreatedBy:           customer.CreatedBy,
			CreatedTime:         customer.CreatedOn,
		})
	}

	return response, nil
}

func (s *CustomerManageService) ImportDelete(ctx context.Context, request *clueDto.ImportDeleteRequest) (*clueDto.ImportDeleteResponse, error) {
	ids := make([]int64, 0)
	ids = append(ids, request.Id)
	params := &cluePb.ImportCustomerDeleteRequest{
		Id: ids,
	}
	_, err := s.customerManageRepository.ImportCustomerDelete(ctx, params)
	if err != nil {
		return nil, err
	}
	return &clueDto.ImportDeleteResponse{}, nil
}

func (s *CustomerManageService) ImportEdit(ctx context.Context, request *clueDto.ImportEditRequest) (*clueDto.ImportEditResponse, error) {
	params := &cluePb.ImportCustomerEditRequest{
		Id:          request.Id,
		CompanyName: request.CompanyName,
	}
	_, err := s.customerManageRepository.ImportCustomerEdit(ctx, params)
	if err != nil {
		return nil, err
	}
	return &clueDto.ImportEditResponse{}, nil
}

func (s *CustomerManageService) ImportCount(ctx context.Context, request *clueDto.ImportCountRequest) (*clueDto.ImportCountResponse, error) {
	count, err := s.customerManageRepository.ImportCustomerCount(ctx, &cluePb.ImportCustomerCountRequest{})
	if err != nil {
		return nil, err
	}
	return &clueDto.ImportCountResponse{
		TotalCount:   count.TotalCount,
		SucceedCount: count.SucceedCount,
		FailedCount:  count.FailedCount,
	}, nil
}

func (s *CustomerManageService) ExportCustomerList(ctx context.Context, request *clueDto.ExportCustomerRequest) (*clueDto.ExportCustomerResponse, error) {
	params := &cluePb.CustomerListRequest{
		Keyword:            request.Keyword,
		Group:              request.Group,
		AreaCodes:          request.AreaCodes,
		CompanyLevel:       request.CompanyLevel,
		CompanyIdentity:    request.CompanyIdentity,
		CompanyLabel:       request.CompanyLabel,
		ResponsibleUserIds: request.ResponsibleUserIds,
		Category:           request.Category,
	}
	data, err := s.customerManageRepository.ExportCustomerList(ctx, params)
	if err != nil {
		return nil, err
	}

	if data == nil || data.JobId == 0 {
		return nil, errors.New("导出任务失败")
	}

	return &clueDto.ExportCustomerResponse{JobId: data.JobId}, nil
}
